//
// Created by 张闳 on 2021/12/3.
// Reference: https://gitee.com/icesky1stm/HashMap
//

#ifndef LIBMCOMMON_MAP_H
#define LIBMCOMMON_MAP_H

typedef void * map_t;

/*********************************************************************
 * 函数功能: 以默认方式创建一个hashmap
 * 入口参数: 无
 * 出口参数: 无
 * 返回值  : 成功，创建的hashmap的指针,强制转换成了void *类型,需要外部void*指针
            失败，返回NULL
 * 调用说明: 以默认的方式创建的hashmap，默认值为XipHashmapInit的默认值
            也就说XipHashmapInit的所有参数都传递为0
            大部分情况都可以使用该函数进行一个新的hashmap的创建，如果想进行
            特殊功能，比如不分配内存，或者修改初始容量之类的，则可以调用
            map_init, 该函数也对外暴露。
 *********************************************************************/
void * map_new();

/*********************************************************************
 * 函数功能: 创建一个hashmap，有更多的参数供特殊情况使用
 * 入口参数: int opacity 初始容量, 默认为16
 *          float factor 加载因子, 一般为0.75f，不建议修改
 *          int malloc_flag 是否分配内存给value:
                1不分配,0和其他分配，具体参见XipHashmapPut的说明
 * 出口参数: 无
 * 返回值  : 成功，创建的hashmap的指针,强制转换成了void *类型,方便调用
            失败，返回NULL
 * 调用说明: 按照传入的信息进行定制的初始hashmap创建,
 *          如果opacity为0,则为默认值16,如果factor为0,则默认为0.75f
 *          如果你没有特殊的要求或特殊的场景，建议更多的使用map_new()
 *********************************************************************/
void * map_init(int opacity , float factor, int malloc_flag);

/*********************************************************************
 * 函数功能: 销毁和释放hashmap，以及它所占用的空间
 * 入口参数: hashmap指针
 * 出口参数: 无
 * 返回值  : 永远返回0
 * 调用说明: 销毁hashmap结构和占用的空间，该函数可以多次调用.
 * 特别注意: 调用该函数之后，需要将hashmap的值置为NULL，防止野指针，
 *          原因同free,fclose等相同。
 *********************************************************************/
int map_free(void * hashmap);

/*********************************************************************
 * 函数功能: 将key和value存入hashmap中
 * 入口参数: void * hashmap_t
 *          char * key 必须是字符串类型
 *          void * value  任何类型，可以是整形，数组或者结构体
 *          int size 在malloc_flag不为1的情况下，用于帮助hasmap创建内存保存value
 * 出口参数: 无
 * 返回值  : 成功，返回保存value的地址
            失败，返回NULL
 * 调用说明: 该函数的实现与map_init的参数malloc_flag有关(默认为0)
            设置为1的情况: 则该散列表不保存实际value，只保留指向value的指针，
                         这意味着你需要在自己为所有的value,此时size参数无效
            设置为0或其他的情况:则该散列表会在创建节点的时候，额外
                         分配内存用于对value数据的保存，调用方在使用Put之后，
                         不需要在保留原value的数据和空间
 *********************************************************************/
void * map_put(void * in_map, char * key, void * value, int size);

/*********************************************************************
 * 函数功能: 根据key找到对应的value的地址
 * 入口参数: void * hashmap_t
 *          char * key 必须是字符串类型
 * 出口参数: 无
 * 返回值  : 成功，返回保存value的地址
            未找到，返回NULL
            失败，返回NULL
 * 调用说明: 该函数的实现与map_init的参数malloc_flag有关(默认为0)
 *********************************************************************/
void * map_get(void * map, char * key);

/*********************************************************************
 * 函数功能: 根据key值从hashmap中查找是否存在,存在返回真,不存在返回假
 * 入口参数: void * hashmap_t
 *          char * key 必须是字符串类型
 * 出口参数: 无
 * 返回值  : int
            成功且为真，返回XIP_HASHMAP_EXIST_TURE
            成功且为假，返回XIP_HASHMAP_EXIST_FALSE
            失败，返回<0的负数
 * 调用说明:
 *********************************************************************/
/***判断是否存在时的返回值***/
#define HASHMAP_EXIST_TURE  1       /*存在- 真*/
#define HASHMAP_EXIST_FALSE 0       /*不存在- 假*/
int map_exists(void * map, char * key);

/*********************************************************************
 * 调用功能: 根据key的值，删除散列表中对应的node
 * 入口参数: void * hashmap_t
 *          char * key 必须是字符串类型
 * 出口参数: 无
 * 返回值  : int
                成功，返回0
                失败，返回<0的负数
 * 出口参数: 无
 * 调用说明:
 *********************************************************************/
int map_remove(void * map, char * key);

/*********************************************************************
 * 调用功能: 打印hashmap中所有的元素,主要用于调试和检查散列分布
 * 入口参数: hashmap的指针
 *           void (ref_func)(int idx, char * key, void * value)
 *           回调函数原型，如果需要自己输出日志等，则可定义该回调函数，如果
 *           不使用，则传值NULL
 * 出口参数: 无
 * 返回值  : 整型,不会失败，一定会返回0，所以不用判断
 * 调用说明: 打印出来的散列分布是竖列的，样式如下，map的分布会根据次数向后空格
            [I][map.c][136][00000000:1]
            [I][map.c][136][00000001:0]
            [I][map.c][136][00000002:1]
            [I][map.c][136][00000003:   3]
            [I][map.c][136][00000004:1]
            [I][map.c][136][00000005:1]
            [I][map.c][136][00000006: 2]
            [I][map.c][136][00000007:0]
            另外，值的显示目前只能显示出字符串类型，其他类型无法显示
 *********************************************************************/
int map_print(void * hashmap, void (*ref_func)(int, char *, void *));

/*********************************************************************
 * 调用功能: 获取当前hashmap中的key：value键值对的个数
 * 入口参数: hashmap的指针
 * 出口参数: 无
 * 返回值  : 整型个数
 * 调用说明:
 *********************************************************************/
int map_key_count(void * hashmap );

/*********************************************************************
 * 函数功能: 获取当前hashmap所占的各种内存的大小
 * 入口参数: void * hashmap_t
 * 出口参数:
 *          mapsize: hashmap结构的大小,可以为NULL
 *          tablesize: 桶的大小 ,可以为NULL
 *          nodesize: 节点总大小, 可以为NULL
 *          keysize: key的总大小, 可以为NULL
 *          valuesize: value的总大小, 可以为NULL
 *
 * 返回值  : int total_size,占用内存总大小
 * 调用说明:
 *********************************************************************/
int map_info(void * hashmap, int * mapsize, int * tablesize, int * nodesize, int * keysize, int * valuesize);



#endif //LIBMCOMMON_MAP_H
